package com.microcm.system.task;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.List;

import jeasy.analysis.MMAnalyzer;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import com.microcm.common.CUtils;
import com.microcm.common.Final;
import com.microcm.member.entity.User;
import com.microcm.system.cache.SystemCacheKeeper;
import com.microcm.system.service.SystemService;
import com.microcm.system.utils.IndexSearcherHolder;
import com.microcmframework.core.context.AppContext;
import com.microcmframework.core.job.JobRunner;

/**
 * 新建用户索引
 * 
 * @author kansum
 */
@Lazy(false)
@Service("userIndexBuildJob")
public class UserIndexBuildJob extends JobRunner
{
	@Autowired
	private SystemService SystemService;

	@Autowired
	private SystemCacheKeeper systemCacheKeeper;

	private File indexRootDir;

	private boolean isExistSegment;

	public UserIndexBuildJob()
	{
		super(UserIndexBuildJob.class.getName(), true, "building user index");
	}

	@Override
	protected String getCfgValue(String key)
	{
		String cfgVal = this.systemCacheKeeper.getSystemConfigValue(key, null);
		if (cfgVal == null)
		{
			cfgVal = AppContext.getInstance().getSysPropValue(key);
		}
		return cfgVal;
	}

	/**
	 * 初始化一些参数
	 */
	@Override
	protected boolean doInitialize()
	{
		// 索引目录
		this.indexRootDir = new File(AppContext.getInstance().getSysPropValue(Final.INDEX_ROOT_DIR), "user");
		if (!this.indexRootDir.exists())
		{
			this.indexRootDir.mkdirs();
		}
		String[] files = this.indexRootDir.list(new FilenameFilter()
		{
			@Override
			public boolean accept(File dir, String name)
			{
				return (name.endsWith(".gen") || name.endsWith(".cfs") || name.endsWith(".cfx"));
			}
		});
		isExistSegment = files == null ? false : files.length > 0;

		return super.doInitialize();
	}

	@Override
	public void doProcess()
	{
		List<?> qryUsersList = null;
		do
		{
			qryUsersList = this.SystemService.queryReadyForBuildIndexUsers();
			if (CUtils.isEmpty(qryUsersList))
				break;
			boolean ret = appendUsersIndex(qryUsersList);
			if (!ret)
				break;
			this.SystemService.updateUsersHasIndex(qryUsersList);
		} while (true);
	}

	/**
	 * 追加商品的索引
	 * 
	 * @author kansum
	 */
	private boolean appendUsersIndex(List<?> qryUsersList)
	{
		Directory indexDir = null;
		try
		{
			// 先将查询索引器关掉
			IndexSearcherHolder.getInstance().closeIndexSearcher(Final.INDEX_USER);

			// 使用极易分词
			Analyzer analyzer = new MMAnalyzer();
			// 接下来是标准的Lucene建立索引和检索的代码
			indexDir = FSDirectory.open(this.indexRootDir);

			IndexWriter writer = null;
			if (isExistSegment)
				writer = new IndexWriter(indexDir, analyzer, false, IndexWriter.MaxFieldLength.UNLIMITED);
			else
				writer = new IndexWriter(indexDir, analyzer, true, IndexWriter.MaxFieldLength.UNLIMITED);

			// 一条条将商品添加到索引中
			for (Object o : qryUsersList)
			{
				User user = (User) o;
				Document doc = new Document();
				Field field = null;
				field = new Field("unid", user.getUnid(), Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS);
				doc.add(field);
				field = new Field("uname", user.getUname(), Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS);
				doc.add(field);
				field = new Field("domain", user.getDomain(), Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS);
				doc.add(field);

				Term pkey = new Term("unid", user.getUnid());
				writer.updateDocument(pkey, doc);
			}
			writer.optimize();
			writer.close();
			indexDir.close();

			this.logger.error("\t... " + qryUsersList.size() + " index has been builded!");

			if (!isExistSegment)
			{
				isExistSegment = true;
			}
			return true;
		}
		catch (IOException e)
		{
			this.logger.error(e.getMessage(), e);
		}
		finally
		{
			try
			{
				if (indexDir != null && IndexWriter.isLocked(indexDir))
				{
					IndexWriter.unlock(indexDir);
				}
				// 无论如何都要开启查询索引器
				IndexSearcherHolder.getInstance().openIndexSearcher(Final.INDEX_USER);
			}
			catch (IOException e)
			{
				this.logger.error(e.getMessage(), e);
			}
		}
		return false;
	}
}
